package org.mfw.ddm.ldm
{
	import flash.events.EventDispatcher;
	import flash.filesystem.File;
	import flash.media.Sound;
	import flash.net.URLRequest;
	
	import org.mfw.interfaces.mdm.IMediaDataManager;
	import org.mfw.obj.events.BoxEvent;
	import org.mfw.obj.events.CoverEvent;
	import org.mfw.obj.events.MediaStreamEvent;
	import org.mfw.obj.list.BoxList;
	import org.mfw.obj.list.SongList;
	import org.mfw.obj.mob.Box;
	import org.mfw.obj.mob.Cover;
	import org.mfw.obj.mob.Song;
	import flash.events.Event;
	
	/**
	 * Der LocalDataManager stellt Funktionen zur Kommunikation mit einem externen Speicher bereit.
	 * Dieser Datenmanager und der Datenmanager für den Ampache MediaServer implementieren Die Schnittstelle für den MediaDataManager. 
	 * */
	public class LocalDataManager extends EventDispatcher implements IMediaDataManager
	{
		private var _path:String; // Der Rootpfad, den der Benutzer 
		private var _blankCoverURL:String = "/assets/blankcover.gif"; // Das Standard Cover, dass angezeigt wird, wenn der Ordner kein Cover beinhaltet
		private var _tempID:Number;
		
		// Fordert die Startbox an (Rootverzeichnis)
		public function getStartBox():Boolean
		{
			this.getBoxByID(1);
			return true; 
		}
		
		// Fordert die Box (Daten über das Verzeichnis) mit der angefragten ID an. z.B: 10000100002
		public function getBoxByID(ID:Number):Boolean 
		{
			var path:String = this.getPathByID(ID); // ermittelt aus der ID den zugehörigen Dateipfad
			
			var directory:File = new File(path); // erstellt aus dem angegebenem Pfad einen Verzeichnisbaum
			var files:Array = directory.getDirectoryListing();
			
			var cover:Cover; // legt das cover an, welches im Ordner liegt
			var boxlist:BoxList = new BoxList(); // legt eine Liste von Ordnern an
			var songlist:SongList = new SongList(); // legt eine Liste von Songs an
			var songID:int = 0; // setzt die aktuelle Song ID auf 0
			
			// durchläuft das Verzeichnis	
			for (var i:uint=0; i < files.length; i++)
			{
				//wenn Objekt im Verzeichnis ein Verzeichnis ist:
				if(files[i].isDirectory) {
					var id:Number = i+1;
					
					// erstellt aus id die endgültige ID für die Box. z.B.: 1000130013500002 - root/Künstler 13/Album 135/CD 2  
					if(i<9999) {
						id = Number(ID.toString() + "0" + (i+1)); 
					}
					if(i<999) {
						id = Number(ID.toString() + "00" + (i+1)); 
					}
					if(i<99) {
						id = Number(ID.toString() + "000" + (i+1)); 
					}
					if(i<9) {
						id = Number(ID.toString() + "0000" + (i+1)); 
					}
					
					var currentBox:Box = new Box(id); // erstellt eine Box aus der ermittelten ID und erzeugt diese 
					currentBox.name = this.getFileNameByPath(this.getNativePathByID(id)); // holt den Ordnernamen aus dem Dateipfad und weißt diesen als Namen zur Box zu
					boxlist.addElement(currentBox);
				}
				
				//wenn Objekt im Verzeichnis eine Bilddatei ist
				if(files[i].extension == "jpg" || files[i].extension == "jpeg" || files[i].extension == "png")
				{
					var coverURL:String = files[i].url;
					cover = new Cover(ID, coverURL);
				}
				
				// wenn Objekt im Verzeichnis eine MP3 Datei ist
				if(files[i].extension == "mp3")
				{
					songID++;
					
					// erstellt das Datenobjekt welches das Songobjekt benötigt
					var object:Object = new Object();
					object.id = Number(ID + "." + songID);
					object.url = files[i].url;
					object.title = this.getFileNameByPath(files[i].nativePath);
					var currentSong:Song = new Song(object);
					songlist.addElement(currentSong);
				}
			}
			
			// wenn kein Cove im Verzeichnis gefunden wurde
			if(cover == null) {
				cover = new Cover(ID,this._blankCoverURL);
			}
			
			var box:Box = new Box(ID, cover);
			box.name = this.getNativePathByID(ID);
			box.boxList = boxlist;
			if(songlist.length > 0) {
				box.songs = songlist;
			} 
			
			// wirft das Event, welches die erstellte Box enthält			
			this.dispatchEvent(new BoxEvent(BoxEvent.COMPLETE, box));		 
			return true;
		}
		
		// Fordert den Song mit der angefragten ID an. z.B: 10000100002.3
		public function getSongStreamByID(ID:Number):Boolean {
			var boxPath:String = this.getPathByID(this.extractBoxIDfromID(ID));
			var songID:Number = this.extractTypeFromID(ID);
			var tempID:int = 0;
			
			var directory:File = new File(boxPath);
			var files:Array = directory.getDirectoryListing();
							
			for (var i:uint=0; i < files.length; i++)
			{
				if(files[i].extension == "mp3")
				{
					tempID++;
					if(tempID == songID) {
						var object:Object = new Object();
						object.id = Number(ID + "." + songID);
						object.url = files[i].url;
						object.title = this.getFileNameByPath(files[i].nativePath);
						var song:Song = new Song(object);
					}
				}
			}
			
			var sound:Sound = new Sound();
			var urlRequest:URLRequest = new URLRequest(song.songURL);
			sound.load(urlRequest);
			
			// wirft das Event, welches den erstellten Song enthält	
			super.dispatchEvent(new MediaStreamEvent(MediaStreamEvent.SOUND_RECEIVE,sound));
			return true;
		}
		
		// Fordert das Cover mit der angefragten ID an. z.B: 10000100002
		public function getCoverByID(ID:Number):Boolean {
			var boxPath:String = this.getPathByID(ID);
					
			var directory:File = new File(boxPath);
			var files:Array = directory.getDirectoryListing();
							
			for (var i:uint=0; i < files.length; i++)
			{
				if(files[i].extension == "jpg" || files[i].extension == "jpeg" || files[i].extension == "png")
				{
					var cover:Cover = new Cover(ID,files[i].url);
					cover.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, dispatchCover);
				}
			}
			function dispatchCover():void {
				// wirft das Event, welches das erstellt Cover enthält	
				dispatchEvent(new CoverEvent(CoverEvent.COVER_RECEIVED,cover));
			}
			
			return true;
		}
		
		/**
		 * Helfer Funktionen, welche nicht vom Interface gefordert werden
		*/
		
		
		// Funktion wird dazu benötigt um aus der GUI Schicht den ausgeählten Rootordner an die Datenmanager Schicht zu übertragen
		public function setParams(params:Object):Boolean
		{
			if (params.hasOwnProperty("path"))
			  
			{
				this._path = params.path;				
				return true;
			}
			else return false;
		}
		
		public function get debugText():String
		{
			return null;
		}
		
		// Funktion liefert anhand der ID den verzeichnispfad zurück z.B. 100001: C:/Musik/Album 1+
		private function getPathByID(ID:Number):String {
			if(ID == 1) {
				return this._path;
			} else {
				var id:String = ID.toString();
				var currentPath:String = this._path;
			
				for(var f:int = 1; f < id.length; f = f+5) {
					var directory:File = new File(currentPath);
					var files:Array = directory.getDirectoryListing();
					
					var currentID:Number = Number(id.charAt(f) + id.charAt(f+1) + id.charAt(f+2) + id.charAt(f+3) + id.charAt(f+4)); 
					
					if(files[currentID-1].isDirectory) {
						currentPath = files[currentID-1].url;
					}
				}
				return currentPath;			
			}
		}
		
		// erstellt aus einer ID den aktuellen Ordnername
		private function getNativePathByID(ID:Number):String {
			if(ID == 1) {
				return this._path;
			} else {
				var id:String = ID.toString();
				var currentPath:String = this._path;
			
				for(var f:int = 1; f < id.length; f = f+5) {
					var directory:File = new File(currentPath);
					var files:Array = directory.getDirectoryListing();
					
					var currentID:Number = Number(id.charAt(f) + id.charAt(f+1) + id.charAt(f+2) + id.charAt(f+3) + id.charAt(f+4)); 
					
					if(files[currentID-1].isDirectory) {
						currentPath = files[currentID-1].nativePath;
						//currentPath = this.getFolderNameByPath(currentPath);
					}
				}
				return currentPath;			
			}
		}
		
		// generiert den Dateinamen oder Ordnernamen von einem Dateipfad
		private function getFileNameByPath(path:String):String {
			var newPath:String = "";
			var i:int = path.length-1;
			
			for(i; i > 0; i--) {
				if(path.charAt(i) == "\\" || path.charAt(i) == "/") {
					return newPath;
				} else {
					newPath = path.charAt(i) + newPath;
				}
			}
			return newPath;
		}
		
		// extrahiert die Song ID aus einer ID z.B.: 10002300002.4 - 4
		protected function extractTypeFromID(ID:Number):Number {
			return Number(ID.toString().substr(ID.toString().length-1,1));
		}
		
		// extrahiert die Box ID aus einer ID z.B.: 10002300002.4 - 10002300002
		protected function extractBoxIDfromID(ID:Number):Number {
			return Number(ID.toString().substr(0,ID.toString().length-2));
		}
		
	}
}